#ifndef SIGNAL_H
#define SIGNAL_H

#include <iostream>

class Signal{
public:
	typedef double ValueType;

	Signal(size_t inChannels = 0, size_t inElements = 0);
	~Signal();

	int Channel() const{ return mNumChannels; }
	int Element() const{ return mNumElements; }

	void InitSignal(size_t inChannel, size_t inElement);

	const ValueType& Value(size_t inChannel, size_t inElement) const;
	Signal& SetValue(size_t inChannel, size_t inElement, ValueType inValue);

	const ValueType& operator()(size_t inChannel, size_t inElement) const;
	ValueType&		 operator()(size_t inChannel, size_t inElement);

	std::ostream& WriteBinary(std::ostream&) const;
	std::istream& ReadBinary(std::istream&);
	//std::ostream& WriteValueBinary(std::ostream&, size_t inChannel, size_t inElement) const;
	//std::istream& ReadValueBinary(std::istream&, size_t inChannel, size_t inElement);

private:
	template<typename T> static void PutLittleEndian(std::ostream&, const T&);
	template<typename T> static void GetLittleEndian(std::istream&, T&);

private:
	ValueType*	mpValue;
	int			mNumChannels;
	int			mNumElements;
};

inline const Signal::ValueType& Signal::Value(size_t inC, size_t inE) const
{
	return operator()(inC, inE);
}

inline Signal& Signal::SetValue(size_t inC, size_t inE, ValueType inV)
{
	operator()(inC, inE) = inV;
	return *this;
}

inline const Signal::ValueType& Signal::operator()(size_t inC, size_t inE) const
{
	return mpValue[inC * mNumElements + inE];
}

inline Signal::ValueType& Signal::operator()(size_t inC, size_t inE)
{
	return mpValue[inC * mNumElements + inE];
}

#endif